#ifndef __Utility_h__
#define __Utility_h__

#include <cstring>
#include <string>

namespace Utility
{
	static const float	Pi(3.14159265359f);

#	define MAXINT	((int)(((unsigned int)~((unsigned int)0)) >> 1))

	template<typename Type>
		inline Type lerp(const Type a, const Type b, const float perc)
		{
			return a * perc + (1.0f - perc) * b;
		}
	//----------------------------------------------------
	template<typename Type>
		inline bool isInBound(const Type &lower, const Type &upper, const Type &value)
		{
			return value >= lower && value <= upper;
		}

	//----------------------------------------------------
	inline char* copyStr(const char *str)
	{
		size_t length = strlen(str) + 1;
		char *target = new char[length];
		memcpy(target, str, sizeof(char) * length);
		return target;
	}

	extern std::string	gTmpPath;
	//----------------------------------------------------
	inline const char* getResource(const char *fileName)
	{
		gTmpPath = "..\\Resources\\";
		gTmpPath += fileName;
		return gTmpPath.c_str();
	}
	inline const char* getMap(const char *fileName)
	{
		gTmpPath = "..\\Resources\\maps\\";
		gTmpPath += fileName;
		return gTmpPath.c_str();
	}

	//----------------------------------------------------
	template<typename Type>
		inline Type minimum(const Type &left, const Type &right)
		{
			return left < right ? left : right;
		}

	//----------------------------------------------------
	template<typename Type>
		inline Type maximum(const Type &left, const Type &right)
		{
			return left > right ? left : right;
		}

	//----------------------------------------------------
	template<typename Type>
		inline Type clamp(const Type &lower, const Type &upper, const Type &value)
		{
			return maximum(minimum(upper, value), lower);
		}

	//----------------------------------------------------
	template<typename Type>
		inline void swap(Type &left, Type &right)
		{
			Type tmp = left;
			left = right;
			right = tmp;
		}

	//----------------------------------------------------
	template<typename Type>
		inline Type abs(const Type &value)
		{
			return value < 0.0 ? -value : value;
		}
}

#endif // __Utility_h__
